<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018-09-29
 * Time: 13:48
 */

namespace backend\controllers;


use app\models\CtiConfig;
use app\models\CtiFile;
use app\models\CtiGw;
use app\models\CtiZuoxi;
use app\models\CtiZuoxiLoginFlag;
use common\helps\Tools;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper;
use FreeSwitchEventListener;

class CtiManagerController  extends CommonController
{

    public $path = "C:\\\Program Files\\FreeSWITCH\\";
    public $fs_wav_path = "sounds\\zh\\cn\\link\\";
    public $domain = '';//freeswitch的服务器域名
    public $http = 'https';
    public $remark = null;

    public function behaviors()
    {
        return [
            'filter' => [
                'class' => AccessControl::className(),
                'only' => [
                    'get-directory',
                    'upload',
                ],
            ],
        ];
    }

    public function beforeAction($action)
    {
        //拿到配置文件
        $remark = CtiConfig::find()->select('remark')->where(['type'=>'rdhpz_freeswitchDirectory'])->one();
        $this->remark = json_decode($remark->remark);
        $this->domain = $this->remark->domain;
        parent::beforeAction($action);
        //拿到配置文件，拿到cti_config表里面的 软电话配置
        if($this->redis->get("ctiManeger_config")){
            $config = json_decode($this->redis->get("ctiManeger_config"));
        }else{
            $ctiConfig = new CtiConfig();
            $config = $ctiConfig->find()->andWhere(['parent_type'=>'rdhpz'])->one();
            $config = json_decode($config->remark);
        }
        $this->path = $config->path;
        $this->domain = $config->domain;
        $this->http = $config->http;
        return $this;
    }

    //需要在父类里面实现的方法，为true就表示不需要过滤
    public function getFilter(){
        return true;
    }

    /*************************以下是公共的action，可通过接口访问***********************************************/

    /**
     * freeswitch里面的动态注册本地用户，
     * 从本地数据库里面注册用户
     * @return string
     */
    public function actionGetDirectory(){
        $domain = $this->domain;
        $password = "123456";
        $usersXml = "";
        if (empty($vars)){
            $ctiZuoxi = CtiZuoxi::find()->select("*")->all();
            if (!empty($ctiZuoxi)){
                foreach ($ctiZuoxi as $k=>$v){
                    $user = $v->number;
                    $userXml = '
                    <user id="'.$user.'">
                        <params>
                          <param name="password" value="'.$password.'"/>
                          <param name="vm-password" value="'.$password.'"/>
                        </params>
                        <variables>
                          <variable name="toll_allow" value="domestic,international,local"/>
                          <variable name="accountcode" value="'.$user.'"/>
                          <variable name="user_context" value="default"/>
                          <variable name="effective_caller_id_name" value="Extension '.$user.'"/>
                          <variable name="effective_caller_id_number" value="'.$user.'"/>
                          <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
                          <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
                          <variable name="callgroup" value="techsupport"/>
                          <variable name="sound_prefix" value="$${sounds_dir}/zh/cn/link"/>
                          <variable name="language" value="zh"/>
                        </variables>
                    </user>';
                    $usersXml .= $userXml;
                }
            }
            $vars = '<document type="freeswitch/xml">
    <section name="directory">
        <domain name="'.$domain.'">
            <params>
              <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
            </params>
            <groups>
              <group name="default">
                <users>'.$usersXml.'
                </users>
              </group>
            </groups>
        </domain>
    </section>
</document>';
        }
        //新增动态的坐席注册
        return $vars;
    }

    /**
     * freeswitch里面的动态注册网关，将文件直接保存到freeswitch的
     * conf/sip_profiles/external文件夹内
     * @return string
     */
    public function actionSaveSipProfiles(){
        $CtiGw = CtiGw::find()->select("*")->all();
        $remark = $this->remark;
        //需要写到freeswitch里面的scripts/call_multi_gw.lua文件里面的数据
        $luaGateways = "";
        if (!empty($CtiGw)){
            foreach ($CtiGw as $k=>$v){
                $number = $v->number;
                if ($v->bind_number[0] == "0"){
                    $bind_number = substr($v->bind_number,1,strlen($v->bind_number));
                }else{
                    $bind_number = $v->bind_number;
                }
                $password = $v->password;
                $luaGateways .= '"gw'.$number.'",';
                $userXml = '<gateway name="gw'.$number.'">
    <param name="realm" value="'.$remark->realm.'"/>
    <param name="register-proxy" value="'.$remark->register_proxy.'"/>
    <param name="username" value="+86'.$bind_number.'@'.$remark->realm.'"/>
    <param name="password" value="'.$password.'"/>
    <param name="register" value="true"/>
    <param name="from-user" value="+86'.$bind_number.'"/>
    <param name="extension" value="+86'.$bind_number.'"/>
    <param name="proxy" value="'.$remark->realm.'"/>
    <param name="extension-in-contact" value="true"/>
    <param name="outbound-proxy" value="'.$remark->outbound_proxy.'"/>
    <param name="caller-id-in-from" value="false"/>
    <param name="expire-seconds" value="'.$remark->expire_seconds.'"/>
    <param name="ping" value="'.$remark->ping.'" />
    <param name="sip-trace" value="true"/>
</gateway>';
                $this->ftpSaveFile(ArrayHelper::toArray($remark),'/conf/sip_profiles/external/gw'.$number.'.xml',$userXml);
            }
        }
        //得到最终的需要写入lua文件里面的多个网关 比如 "gw1272","gw1273","gw1275","gw1276","gw1278","gw1279","gw1280","gw1281","gw1282","gw1283"
        $luaGateways = substr($luaGateways,0,strlen($luaGateways)-1);
        //将lua文件内容换掉
        $this->replaceXmlFileContents(ArrayHelper::toArray($remark),'/scripts/call_multi_gw.lua','/gateways = {([\s\S]*)};--repalceGateways/i','gateways = {'.$luaGateways.'};--repalceGateways');
        //删除多余的xml文件
        $files = $this->ftpScanFile(ArrayHelper::toArray($remark),'conf/sip_profiles/external');
        $arr = explode(',',$luaGateways.',"example"');
        foreach ($files as $k=>$v){
            $arr_ = explode('/',explode('.',$v)[0]);
            $t = $arr_[count($arr_)-1];
            if(array_search('"'.$t.'"',$arr)===false){//文件不存在
                $this->ftpDeleteFile(ArrayHelper::toArray($remark),$v);
            }
        }
        $this->execFSBgapi("sofia profile external restart");
        return 1;
    }


    /**
     * 保存到ftp ($remark,'/conf/vars.xml',$res3)
     * @param $remark 配置文件内容 通过如下方式获得
     *  $CtiConfig = CtiConfig::find()->where(['type'=>'rdhpz_freeswitchDirectory'])->one();
        $remark = json_decode($CtiConfig->remark);
     * @param $filename '/conf/vars.xml'
     * @param $res 'asdasdasd'
     */
    public function ftpSaveFile($remark,$filename,$res){
        $tempfile = $this->genRandomFile($res);
        $conn_id = ftp_connect($remark['domain'],$remark['port']) or die("Could not connect");
        ftp_login($conn_id,$remark['account'],$remark['password']);
        $fp2 = fopen($tempfile, "r");
        ftp_fput($conn_id,$remark['path'].$filename,$fp2,2);
        ftp_close($conn_id);
        fclose($fp2);
        unlink($tempfile);
        return 1;
    }

    /**
     * 删除文件
     * @param $remark
     * @param $filename
     * @param $res
     * @return int
     */
    public function ftpDeleteFile($remark,$filename){
        $conn_id = ftp_connect($remark['domain'],$remark['port']) or die("Could not connect");
        ftp_login($conn_id,$remark['account'],$remark['password']);
        ftp_delete($conn_id,$filename);
        ftp_close($conn_id);
        return 1;
    }

    /**
     * 删除文件
     * @param $remark
     * @param $filename
     * @param $res
     * @return int
     */
    public function ftpScanFile($remark,$path){
        $conn_id = ftp_connect($remark['domain'],$remark['port']) or die("Could not connect");
        ftp_login($conn_id,$remark['account'],$remark['password']);
        $files = ftp_nlist($conn_id,$remark['path'].'/'.$path);
        ftp_close($conn_id);
        return $files;
    }

    /**
     * 产生随机的文件不唯一
     * @param $res 写进文件的内容
     * @return string
     */
    public function genRandomFile($res){
        $tempfile = "./temp/temp".Tools::randName();
        if (file_exists($tempfile)){
            $this->genRandomFile();
        }else{
            $fp = fopen($tempfile, "w");
            fwrite($fp,$res);
            fclose($fp);
            return $tempfile;
        }
    }

    /**
     * 文件下载
     * @param $file
     * name 是需要下载后得到的文件名字 比如： 0000.xls
     * file 是文件的网络路径 比如：https://10.105.203.200/crms/backend/web/uploads/yuyin/18/1023/4epcr6.xls
     */
    public function actionDownloadFile(){
        ob_start();
        ob_implicit_flush(false);
        $file = $_POST['file'];
        $name = $_POST['name'];
        $fileinfo = pathinfo($file);
        $file_dir = $fileinfo['dirname'];
        $file_name = $fileinfo['basename'];
        //检查文件是否存在
        $file_path_name = $file_dir . "/" .$file_name;
        $arr = mb_split("uploads",$file_path_name);
        if (count($arr)>1){
            $localfile = "./uploads".$arr[1];
            if (!file_exists ( $localfile )) {
                header('HTTP/1.1 404 NOT FOUND');
            } else {
                //以只读和二进制模式打开文件
                $files = fopen ( $localfile, "rb" );
                //告诉浏览器这是一个文件流格式的文件
                Header ( "Content-type: application/octet-stream" );
                //请求范围的度量单位
                Header ( "Accept-Ranges: bytes" );
                //Content-Length是指定包含于请求或响应中数据的字节长度
                Header ( "Accept-Length: " . filesize ( $localfile ) );
                //用来告诉浏览器，文件是可以当做附件被下载，下载后的文件名称为$file_name该变量的值。
                Header ( "Content-Disposition: attachment; filename=" . $name );
                //读取文件内容并直接输出到浏览器
                echo fread ( $files, filesize ( $localfile ) );
                fclose ( $files );
                exit ();
            }
        }else{
            header('HTTP/1.1 404 NOT FOUND');
        }
    }


    /*************************以下是公共的方法，供内部使用***********************************************/

    /**
     * 共用的拿到列表的方法
     * @param $model
     * @param $type 文件类型
     * @param $page 如果post方式的话就要提交到这里
     * @param $limit 如果post方式的话就要提交到这里
     * @return string
     */
    public function getSearchList($model,$type=[],$page="",$limit="",$params=null){
        try{
            $page = $page==""?isset($_GET['page'])?$_GET['page']:0:$page;
            $limit = $limit==""?isset($_GET['limit'])?$_GET['limit']:0:$limit;
            $search = new $model;
            $dataProvider = $search->search($type);
            $this->pagesDo($dataProvider,$page,$limit);
            $res = [];
            $res['code'] = 0;
            $res['msg'] = "";
            $res['count'] = $dataProvider->totalCount;
            $res['data'] = ArrayHelper::toArray($dataProvider->getModels());
            if (!empty($params)){
                $res['params'] = $params;
            }
            //必须要把数组转化为对象，前端固定的格式
            $result = json_encode((object)$res);
            return $result;
        }catch (\Exception $e){
            Tools::l($e);
        }
    }

    /**
     * 删除文件
     */
    public function actionFileDelete($id){
        $file = CtiFile::findOne($id);
        $res = CtiFile::deleteAll('id='.$id);
        if ($res){//删除文件
            //将文件删除
            $temp = strpos($file->path,$this->https_url);
            $path = substr($file->path,strlen($this->https_url)+$temp,strlen($file->path)-strlen($this->https_url));
            $ress = unlink("./".$path);
            return $ress;
        }
        return $res;
    }

    /**
     * @param $arr 数组
     */
    public function jsonEncode($arr){
        return json_encode((object)$arr);
    }

    /**
     * 修改lua相应的字，将其改成相应的文字
     * @param $name 需要修改的文件的名字
     * @param string $search 需要修改的字 为正则切换
     * 例如 "/gateways={(\S+)}/i"
     * @param string $replace 修改后的字
     */
    public function replaceXmlFileContents($remark,$name,$search,$replace){
        $contents = file_get_contents($remark['root'].'/'.$remark['path'].'/'.$name);
        $result = preg_replace($search,$replace,$contents);
        if ($this->ftpSaveFile($remark,$name,$result)){//内容写入成功
            return 1;
        }else{//内容写入失败
            return 0;
        }
    }

    /**
     * 能够实现自动替换掉相应的name里面的xml文件里面的配置。通过传递相应的参数，参数如下
     * 传递的数组 [agents,agent,name="28888@${domain}",type="callback"]
     * 会查找相应的内容
     * @param $name 文件名字 不能包含 空格等特殊字符
     * @param $search 为数组 [agents,agent,name="28888@${domain}",type="callback"]
     * type="callback" 可以用正则来进行查询匹配，
     * 因为第四个是用来替换的字符，而前面三个是需要查询的条件
     * @param $replace 为数组 [agents,agent,name="28899@${domain}",type="aaa"]
     * @param $flag true 表示要进行解析传进来的内容，为false不解析
     * @param $content true 表示$name传输的为内容，而不是文件，为false文件
     * @return int
     * 如此会自动将 28888 替换成 28899 将callback 替换成 aaa
     */
    public function replaceXmlFileConfig($name,$search,$replace,$flag=false,$content=false){
        //把需要替换的进行特殊字符的替换
        $search_ = "";
        if($flag){
            foreach ($search as $k=>$v){
                $search_[$k] = str_replace(["$","(",")"],["\\$","\\(","\\)"],$v);
            }
        }else{
            $search_ = $search;
        }
        $cmd_start = "/";
        $cmd0 = '<';
        $cmd1 = $search_[0];
        $cmd2 = '>';
        $cmd3 = '([\s\S]*)';
        $cmd30 = '<';
        $cmd4 = $search_[1];
        $cmd5 = '([\s\S]*)';
        $cmd6 = $search_[2];
        $cmd7 = '([\s\S]*)';
        $cmd8 = $search_[3];
        $cmd_end = '/U';
        if ($content){
            $contents = $name;
        }else{
            stream_context_set_default(array(
                    'ssl'                => array(
                    'peer_name'          => 'generic-server',
                    'verify_peer'        => FALSE,
                    'verify_peer_name'   => FALSE,
                    'allow_self_signed'  => TRUE
                )));
            $search_ = [' '];
            $replace_ = ['%20'];
            $name = str_replace($search_,$replace_,$name);
            $contents = file_get_contents($name,FALSE);
        }
        $searchs = $cmd_start.$cmd0.$cmd1.$cmd2.$cmd3.$cmd30.$cmd4.$cmd5.$cmd6.$cmd7.$cmd8.$cmd_end;
        $replaces = $cmd0.$replace[0].$cmd2.'${1}'.$cmd30.$replace[1].'${2}'.$replace[2].'${3}'.$replace[3];
        $result = preg_replace($searchs,$replaces,$contents);
        return $result;
    }



    /**
     * 将内容写到文件里面
     * @param $name
     * @param $result
     * @return int
     */
    public function writeToFile($name,$result){
        $search_ = [' '];
        $replace_ = ['%20'];
        $name = str_replace($search_,$replace_,$name);
        if (file_put_contents($name,$result, FILE_TEXT)>0){//内容写入成功
            return 1;
        }else{//内容写入失败
            return 0;
        }
    }



    /*************************以下是执行freeswitch的命令***********************************************/
    /**
     * 远程连接freeswitch
     */
    public function actionSetFs(){
        $res = $this->execFSBgapi($_POST['data']);
        if (trim($res)=='' || strpos($res[0],"+OK")>=0 ){
            if($_POST['action']=="signin"){//签入,freeswitch需要定时的查询后台数据判断客户端是否连接上线
                $this->execFSApi(["luarun check_zuoxi.lua ".$_POST['zuoxi']]);
            }elseif ($_POST['action']=="signout"){//签出，freeswitch关闭定时检查
            }
            return 1;
        }else{
            return 0;
        }
    }
        /**
     * 执行freeswitch的命令行
     */
    public function execFreeswitchCmd2($cmd){
        $cmd = str_replace(["\"","'"],["\\\"","\'"],$cmd);
        $path = 'php.exe';
        $cmd='-r "system(\''.$cmd.'\');" -d disable_functions = ';//重新定义disable_functions函数
        $phpwsh=new \COM("Wscript.Shell") or die("Create Wscript.Shell Failed!");//通过"Wscript.Shell"来实现，不然会出现php资源不足的问题
        $exec=$phpwsh->exec($path.' '.$cmd);
        $stdout = $exec->StdOut();
        $stroutput = $stdout->ReadAll();
        $result = explode("\n",$stroutput);
        return $result;
    }
    /**
     * 坐席登录后定时 提示freeswitch是否在线的标志数据库
     */
    public function actionSaveZlg(){
        $time = time();
        $model = new CtiZuoxiLoginFlag();
        $model = $model->find()->select("*")->where(['zuoxi'=>$_POST['zuoxi']])->one();
        $res = true;
        if ($model){
            if ($_POST['sign'] == 'sign'){//说明是第一次手动点击的签入，不是其自己循环的
                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000),'diff'=>intval($_POST['time']/1000)-$time]);
            }else if($_POST['sign'] == 'loop'){
                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000)]);
            }else if($_POST['sign'] == 'unsign'){
                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000)]);
            }
        }else{
            $model = new CtiZuoxiLoginFlag();
            $model->zuoxi = $_POST['zuoxi'];
            $model->time = intval($_POST['time']/1000);
            $model->diff = $model->time-$time;
            $res = $model->save();
        }
        return $res;
    }
    public function actionGetFs(){
        $res = $this->execFSBgapi($_POST['data']);
        return $res;
    }

    /**
     * $cmdArr 参数是 是数组 或者，号截断的字符串命令
     * 执行freeswitch的命令行 php端可以实现
     */
    public function execFSApi($cmdArr)
    {
        $myFSEventListener = new \FreeSwitch\FreeSwitchEventListener();
        $myFSEventListener->setHost($this->domain);
        if (count($cmdArr)<=0) {
            $cmdArr = explode(",",$cmdArr);
        }
        $ress = "";
        foreach ($cmdArr as $k=>$v){
            $res = $myFSEventListener->event_socket_request("api ".$v);
            $ress .= $res;
        }
        return $ress;
    }

    /**
     * $cmdArr 参数是 是数组
     * 执行freeswitch的命令行 php后端可以实现
     */
    public function execFSBgapi($cmdArr)
    {
        $myFSEventListener = new \FreeSwitch\FreeSwitchEventListener();
        $myFSEventListener->setHost($this->domain);
        if (is_array($cmdArr)<=0) {//不是数组就切割
            $cmdArr = explode(",",$cmdArr);
        }
        $ress = "";
        foreach ($cmdArr as $k=>$v){
            $res = $myFSEventListener->event_socket_request("bgapi ".$v);
            $ress .= $res;
        }
        return $ress;
    }

    /**
     * $cmdArr 参数是 是数组
     * 执行freeswitch的命令行，命令行
     * event等命令 event socket命令
    */
    public function execFS($cmdArr)
    {
        $myFSEventListener = new \FreeSwitch\FreeSwitchEventListener();
        $myFSEventListener->setHost($this->domain);
        if (count($cmdArr)<=0) {
            $cmdArr = explode(",",$cmdArr);
        }
        $ress = "";
        foreach ($cmdArr as $k => $v) {
            $res = $myFSEventListener->event_socket_request($v);
            $ress .= $res;
        }
        return $ress;
    }
//    /******************
//     * 以上是php ,以下是node js的
//     */
//    public function actionSetFs(){
//        $cmd = "";
//        foreach ($_POST['data'] as $k=>$v){
//            $cmd .= $v.",";
//        }
//        $cmd = substr($cmd,0,strlen($cmd)-1);
//        $res = $this->execFreeswitchCmd($cmd);
//        $count = 0;
//        foreach ($res as $k=>$v){
//            if(strpos($v,"+OK")!==false){
//                $count++;
//            }
//        }
//        if ($count==count($_POST['data'])){//签入成功，签出成功，
//            if($_POST['action']=="signin"){//签入,freeswitch需要定时的查询后台数据判断客户端是否连接上线
//                $this->execFreeswitchCmd2("fs_cli -x \"luarun check_zuoxi.lua ".$_POST['zuoxi']."\"");
//            }elseif ($_POST['action']=="signout"){//签出，freeswitch关闭定时检查
//
//            }
//            return 1;
//        }else{
//            return 0;
//        }
//    }
//    /**
//     * 坐席登录后定时 提示freeswitch是否在线的标志数据库
//     */
//    public function actionSaveZlg(){
//        $time = time();
//        $model = new CtiZuoxiLoginFlag();
//        $model = $model->find()->select("*")->where(['zuoxi'=>$_POST['zuoxi']])->one();
//        $res = true;
//        if ($model){
//            if ($_POST['sign'] == 'sign'){//说明是第一次手动点击的签入，不是其自己循环的
//                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000),'diff'=>intval($_POST['time']/1000)-$time]);
//            }else if($_POST['sign'] == 'loop'){
//                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000)]);
//            }else if($_POST['sign'] == 'unsign'){
//                $model->updateAttributes(['zuoxi'=>$_POST['zuoxi'],'time'=>intval($_POST['time']/1000)]);
//            }
//        }else{
//            $model = new CtiZuoxiLoginFlag();
//            $model->zuoxi = $_POST['zuoxi'];
//            $model->time = intval($_POST['time']/1000);
//            $model->diff = $model->time-$time;
//            $res = $model->save();
//        }
//        return $res;
//    }
//    /**
//     */
//    public function actionGetFs(){
//        $cmd = "";
//        foreach ($_POST['data'] as $k=>$v){
//            $cmd .= $v.",";
//        }
//        $cmd = substr($cmd,0,strlen($cmd)-1);
//        $res = $this->execFreeswitchCmd($cmd);
//        return json_encode($res);
//    }
//
//    /**
//     * $cmdArr 参数是 是数组
//     * 执行freeswitch的命令行 php后端可以实现
//     */
//    public function execFSBgapi($cmdArr)
//    {
//        if (is_array($cmdArr)<=0) {//不是数组就切割
//        }else{
//            $cmdArr = join(",",$cmdArr);
//        }
//        $ress = $this->execFreeswitchCmd($cmdArr);
//        return $ress;
//    }
//
//    /**
//     * 只能执行一条freeswitch的命令行
//     */
//    public function execFreeswitchOneCmd($cmd){
//        exec('fs_cli -x "'.$cmd.'"',$return);
//        return $return;
//    }
//
//    /**
//     * 执行freeswitch的命令行
//     */
//    public function execFreeswitchCmd($cmd){
//        // 用node的esl进行运行跑命令行，实现运行freeswitch里面的命令
//        //这个是后台跑的程序，但是拿不到结果
////        try{
////            exec('node ../../console/myconsole/execCmd.js '.json_encode($cmd),$return);
////        }catch (\Exception $e){//上面的出现了异常就执行下面的
//            $path =\Yii::$app->basePath;
//            $cmd='node '.$path.'\\..\\console\\myconsole\\execcmd.js '.json_encode($cmd);
//        $return =$this->execFreeswitchCmd2($cmd);
////        }
//        return $return;
//    }
//
//    /**
//     * 执行freeswitch的命令行
//     */
//    public function execFreeswitchCmd2($cmd){
//        $cmd = str_replace(["\"","'"],["\\\"","\'"],$cmd);
//        $path = 'php.exe';
//        $cmd='-r "system(\''.$cmd.'\');" -d disable_functions = ';//重新定义disable_functions函数
//        $phpwsh=new \COM("Wscript.Shell") or die("Create Wscript.Shell Failed!");//通过"Wscript.Shell"来实现，不然会出现php资源不足的问题
//        $exec=$phpwsh->exec($path.' '.$cmd);
//        $stdout = $exec->StdOut();
//        $stroutput = $stdout->ReadAll();
//        $result = explode("\n",$stroutput);
//        return $result;
//    }
}